

// Copyright (C) 2013-2014 Altera Corporation, San Jose, California, USA. All rights reserved.
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to
// whom the Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// 
// This agreement shall be governed in all respects by the laws of the State of California and
// by the laws of the United States of America.

#ifndef MATRIXMULT_H
#define MATRIXMULT_H
#include "InfInt.h"

using namespace std;
// Block size. Affects the kernel, so if this value changes, the kernel
// needs to be recompiled.
#ifndef BLOCK_SIZE
#define SIZE 64 // default value
typedef unsigned int uint;

ulong d[64]=
 {0xbe8e6815ac08f771, 0x441dd579f4618f00, 0x9687f5530d35fd40, 0xa3e1ad51cb3cc18a,
  0x97434839806420e7, 0xe9350a109d9fff0c, 0xd56c7ae8da978b6, 0x5bd53701884fac59,
  0x68d0415b75f7d4fd, 0x347a786169d52a44, 0x694175f39b0c209a, 0xa663f7567591651c,
  0x683f99238bb7d897, 0xeabc7d9197063eec, 0x5338b5f87168c867, 0xeded58e57c647b24,
  0x23a8610cfcea2a1a, 0x9c0c8a2128dae731, 0x1378b5d033092585, 0xa22e3d153cc5ac42,
  0x6dba863c07b73781, 0xb5ea05d90897d0a, 0x5a3217642b55b07b, 0xf3d058303cb2cc50,
  0xb9b8be7c721def88, 0xe983331defeafaec, 0x250c002dde41215f, 0xe0e0d46e3b65ed80,
  0x88cf132ab754df05, 0x3bae937b531f6837, 0xc64e92146d92eb10, 0xa2ab83b755dee2af,
  0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0};

ulong n[64]=
{ 0x9bebbb80d92aeacb, 0xa4d1c50c3cb90d4, 0xe4e7e25452f7614, 0x7cc9ed9a765f73db,
  0xcda74149c6d68b4c, 0xe8098f53152a6e1a, 0x8093dd18a9a92d54, 0x15ec5fc2a0a828e2,
  0xe5177a98942bc34c, 0x3c827519ad52efe3, 0xcf2c93e82b953313, 0xf26995e04fac8397,
  0xa67c43e467d7e2c3, 0xadeb65d6ee0c1d71, 0x92b3b27fc92f3b26, 0xb59279afb2f7a7d3,
  0x3bcc26e2bb9ebb71, 0xab1863fb3ce40c8, 0xb5de6a7732e12542, 0x165caa7b91861a94,
  0x725be0b8ef25a5b9, 0x1966f40feea0d58e, 0x1dc65fbb0b82c902, 0x159ec68e4aff1b39,
  0x15530655f6e7ffbe, 0x61795655982ee535, 0x6425b6efd4f8b3da, 0x80a538fbea13bc7f,
  0x79dffe13ca43e033, 0x8af279f488d1c203, 0xce83e60e056a3f3e, 0xa4ae21de8f3735df,
  0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0};
  
ulong e[64] = {0x10001,0,0,0,0,0,0,0,
                            0,0,0,0,0,0,0,0,
                            0,0,0,0,0,0,0,0,
                            0,0,0,0,0,0,0,0,
                            0,0,0,0,0,0,0,0,
                            0,0,0,0,0,0,0,0,
                            0,0,0,0,0,0,0,0,
                            0,0,0,0,0,0,0,0};//10001
                            
ulong m[64]={0xb4b27ad703d4fa24, 0xd3c96bce64a17dce, 0x65ad5abcb8d02c38, 0xb5ebca1204b6350,
  0x61fb18548bd62301, 0x5bab7d4f64a7f35b, 0xbe226e7a22c691ff, 0x98b0cb35a79b7bbc,
  0x965158b69eecf1cf, 0xf1fb3c605c121a0e, 0x4d7c7b3260ed8ab, 0x8df7998ff8b804b5,
  0x905492f065bd19da, 0x4b9dde4196c78bf6, 0x8b8908ded78103a, 0x476327f0dbb8a456,
  0x3174e8136aeacd64, 0x2c26d599a96d03a8, 0x27c9105cf2fa85c7, 0x3e412f5c401d590e,
  0x736aac12037a248f, 0x2d903d61a4d990c0, 0x57482d4c5660680b, 0x8eabb75744ec4cab,
  0xa1dc2a1be4ee12d2, 0x22b54743cf247c9a, 0x4239ac666409c51c, 0xb690498a6225b2db,
  0xb9b4a7d25c7c94a, 0x3962f13fa5d6f845, 0xd10858486b39853a, 0x6376645a50609677,
  0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0};
  
ulong c[64] = {0x476ee3e55362531b, 0x40046685e4a5a5e2, 0x8561bfa09d1fb094, 0x91c592439f0049b,
  0x840fd7dd5aab5393, 0x303c8b58c44c3f9, 0xa31150b5a2f22600, 0xe8846895cb2338e5,
  0x1fcc31b14435b329, 0xea82888850564064, 0x986686639f9cef69, 0x1182b15729e952e,
  0x6cdef231c4f961ac, 0x83dea5acd0d07ff2, 0xcce8b0e99196ccb3, 0xbd6f7aaeb41bb1d3,
  0x2f7dbe86a11b6ff2, 0x7ca8194e24c655f1, 0x74cb9837581c67a8, 0x11b7724f31faae18,
  0xb4b8a6893ac155d0, 0xed75d6052855ea6e, 0xe08d924cb7fd06b8, 0xb3eaf0af1d2e9dfd,
  0xadc4c7265ae5e788, 0xc2c989c1b36d9be4, 0xf3981127287f2c21, 0x229b47f6661e548a,
  0xe522f751b0da3347, 0x685b83795f46e1d1, 0x308353e3859cd058, 0x20994a5fa579a,
                         0,0,0,0,0,0,0,0,
                            0,0,0,0,0,0,0,0,
                            0,0,0,0,0,0,0,0,
                            0,0,0,0,0,0,0,0};

////76
//ulong d[64] = {0xbe8e6815ac08f771, 0x441dd579f4618f00, 0x9687f5530d35fd40, 0xa3e1ad51cb3cc18a, 0x97434839806420e7, 
//  0xe9350a109d9fff0c, 0xd56c7ae8da978b6, 0x5bd53701884fac59, 0x68d0415b75f7d4fd, 0x347a786169d52a44, 
//  0x694175f39b0c209a, 0xa663f7567591651c, 0x683f99238bb7d897, 0xeabc7d9197063eec, 0x5338b5f87168c867, 
//  0xeded58e57c647b24, 0x23a8610cfcea2a1a, 0x9c0c8a2128dae731, 0x1378b5d033092585, 0xa22e3d153cc5ac42, 
//  0x6dba863c07b73781, 0xb5ea05d90897d0a, 0x5a3217642b55b07b, 0xf3d058303cb2cc50, 0xb9b8be7c721def88, 
//  0xe983331defeafaec, 0x250c002dde41215f, 0xe0e0d46e3b65ed80, 0x88cf132ab754df05, 0x3bae937b531f6837, 
//  0xc64e92146d92eb10, 0xa2ab83b755dee2af,
//                           0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//
//ulong n[64] = {0x9bebbb80d92aeacb, 0xa4d1c50c3cb90d4, 0xe4e7e25452f7614, 0x7cc9ed9a765f73db, 0xcda74149c6d68b4c, 
//  0xe8098f53152a6e1a, 0x8093dd18a9a92d54, 0x15ec5fc2a0a828e2, 0xe5177a98942bc34c, 0x3c827519ad52efe3, 
//  0xcf2c93e82b953313, 0xf26995e04fac8397, 0xa67c43e467d7e2c3, 0xadeb65d6ee0c1d71, 0x92b3b27fc92f3b26, 
//  0xb59279afb2f7a7d3, 0x3bcc26e2bb9ebb71, 0xab1863fb3ce40c8, 0xb5de6a7732e12542, 0x165caa7b91861a94, 
//  0x725be0b8ef25a5b9, 0x1966f40feea0d58e, 0x1dc65fbb0b82c902, 0x159ec68e4aff1b39, 0x15530655f6e7ffbe, 
//  0x61795655982ee535, 0x6425b6efd4f8b3da, 0x80a538fbea13bc7f, 0x79dffe13ca43e033, 0x8af279f488d1c203, 
//  0xce83e60e056a3f3e, 0xa4ae21de8f3735df,
//                           0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//  
//ulong e[64] = {0x10001,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};//10001
//
//ulong R[64] = {0xfa0d0faa,0xb50619e6,0x200b4062,0xf8eb5762,0x200b4062,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0};
//               
//ulong m[64] = {0x5a392a6a95eae363, 0xb76d19888783d07a, 0xa7eef2e98ebe2654, 0x2edceed4673c8435, 0xab60ec2f10c5b99b, 
//  0x96c19c906c4291f8, 0x57554f9196da86bb, 0xce1949dae98dd1de, 0x4309716ab61ff0b9, 0xca702c4238fd6447, 
//  0xda81dd624f1bae8f, 0x6870e06de73daf2e, 0x2fc9eaa7d94ac634, 0xa8b0eb6ee67c00ec, 0xf84ca896f3072d2f, 
//  0x7215bd063ae28084, 0xebf3d1af36190082, 0x767e4313ddbba631, 0xc343db6f19a47e43, 0xfe3fa9768b47c5c6, 
//  0xaf7f4ee912cec800, 0x6a347dfc9cec0f74, 0x3cd67c4febaefb8f, 0x61121fc8214b0599, 0x7d1121ba52046def, 
//  0x11702e03543cb1db, 0xc03e3b1702aced1d, 0xc1f66d88861caa99, 0x7981bada9f1ec749, 0x3edce0dc17f32fca, 
//  0x91c88e1d10132541, 0x251d4e81aaa8d56e,
//                           0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//  
//ulong c[64] = {0x6f776f726c642e0a, 0x69e92f0068656c6c, 0xfd49e6174d655f05, 0x4a09b9248fda7c32, 0xdcf5f1ba7161dbf8, 
//  0x1e264a22e5581fc9, 0x31a43b4a3d093a2d, 0x3f77547830fb7afc, 0x80ba788ac1719050, 0x668667559d72695b, 
//  0x339187bc629d05ac, 0xb37d5e337c2cb514, 0xb81e0d658c9f0ab7, 0x9837ccee5570c28f, 0xfa7b69435d12021f, 
//  0x8348cef8a66f0b79, 0xa562d3e4d0ad7867, 0xbb7b4ee97b518887, 0x712a1b3903464324, 0x9c174a90ceb8ff33, 
//  0x798e71180164a6fd, 0x60e8184658326c42, 0xe78d9e001837d4f, 0x96094a28315cf505, 0xfcadf30e3dd377eb, 
//  0x46f9fd950f96f9ed, 0x1ecc360a4b91b028, 0x703edb85e1e40c4a, 0xf4e9b21f5f448b96, 0xb466665636dd9f5e, 
//  0xba2a6a5712b8bcd8, 0x26d55e9a36a74,
//                           0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//
//
////original,
//ulong n[64] = {0x99a253d3a202bf11, 0x25afe61cb125bfb4, 0x320a508de1a2134a, 0x3275a43aa8677b87, 0x74b5069b5c448dfb, 
//                           0xe35344580b2efd29, 0x2d0c77fc97eb094, 0x1cd843fee752c9cf, 0xec68d9c6badfec5a, 0xd1ab9248ba198e12, 
//                           0xf3aaa960bf4daa79, 0x4d570655212225db, 0x10b5853b6694f0fb, 0x74e72500abf80f5c, 0x89c9c6930c2202e7, 
//                           0x8c92acee0fdc2348, 0x2795e542cbd1d510, 0xbcf406b88f8e1007, 0xf6bb12ab8721c32f, 0xf938352bf4e69a0e, 
//                           0x21de534b90eafdea, 0x6d6df28bb4552bd6, 0x10b7c297447e8734, 0x47b6df49d23ffaa2, 0x6ba2a2b526ce67e2, 
//                           0xfd32e295836cc48, 0x66b1c5f57a855dc2, 0x94d0722f8785594b, 0x38ceee221ce9913b, 0x2822d3b9fee0dee4, 
//                           0xca667ae529c5f349, 0xf384f39236dcb246,
//                           0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0}; //       
//                                           
//ulong e[64] = {0x10001,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};//10001
//
//ulong R[64] = {0xfa0d0faa,0xb50619e6,0x200b4062,0xf8eb5762,0x200b4062,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0};
//
//ulong d[64] = {0xb441c7ebbe238401, 0xc76380c6b86b0637, 0x5fce31a34e2312c2, 0xf062df6b75fcc4a4, 0xc65dbca33a762987, 
//                   0x15d2e8361588a71d, 0xe793665b6fcc0346, 0xf74aef6e97238678, 0xb92793de30a6a8de, 0x14e122a8f5094d4a, 
//                   0x9c5d128b73d4b8af, 0x696d1a3d916f7097, 0x823f51e6cf264b2f, 0x952dae87ded6ae00, 0x37dbedcafa9abd09, 
//                   0xfee3b6179c4032e9, 0x13701e3015429231, 0xf1fa5d781e9a6377, 0xb7e0301007e6114, 0xd95e9bdcb18c98f2, 
//                   0xfdfcaf85ae632457, 0x40d9543bb08f4d9d, 0x44b1dc9ae35832bc, 0xf46222b4e0e8dac, 0x223bb7af45192c0d, 
//                   0xe01864a9253af7a4, 0xb6355f50a0889624, 0xb960dbbd501e718a, 0x8afd44aa7e3f671b, 0xd8e6e0b367c18335, 
//                   0x211427cc6b4ee2ae, 0xeaf45c0db6e139,
//                   0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//
//ulong m[64] = {0xb7c0c73f585ad041, 0xa862de3c9cdb5eaf, 0x2f18a69b9898039d, 0x83f9fe976b5b5c54, 0xd5b3a93ac7602df3, 
//                           0x3035ded899d326d, 0xf11fe5be2a319c00, 0x2668fee61eeef483, 0x77d309218bcbbcb8, 0xf38b895a55a15197, 
//                           0xa2a89077b42eb351, 0x3d8ffe01f433ebb, 0xf420ad214cbf3c5a, 0x456854867c3c4ff2, 0x21177fa4c59df6d3, 
//                           0xf2dc70af579777cd, 0x33f0f21bce539a66, 0xf103dcfdb76a33cb, 0x3fa411bc7f56a9f0, 0x65cb8ac122212ed2, 
//                           0x37c14956cc261acc, 0xffe2c3f1090a529, 0xef6757b4d65796de, 0x7f518794d7589806, 0x631725993e1050d9, 
//                           0x71816c73355a628c, 0x40e5a450739f9a30, 0x4ed8c9455d01c355, 0xd41a76dedde6979d, 0x16f3cef24dfabf3, 
//                           0x9826733cd79c6ca5, 0x2721a98fcdca1,
//                           0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//
////ulong c[64] = {0xc0b41f0b588ef34e, 0x4e158564eb1423fd, 0xb27fb37a1147b467, 0xe869772d354328ef, 0xc07a5c76884ffa60, 
////                         0x96ea22b444ab4dd4, 0x304e80a99ed497e3, 0x70da2b12405e8195, 0x9d0cef0f4148207b, 0x5572103e1f1a973b, 
////                         0x976a3cd65c1e31d6, 0xa5eff7b275c735a7, 0x5f0a9002255ea577, 0xc0fb4c2cc5541aa3, 0x633785b988b15abb, 
////                         0xef7fa4827b96f615, 0x1a3d50a8cc4c1eb5, 0xb00d496a09f052d8, 0xf9c6b5ad3150fff8, 0xae227807fbf81d65, 
////                         0x650caf0513625fcb, 0xf2239eb6204ee718, 0x5a44582157b73785, 0x24802cd11d3b702f, 0xabf86b4ff22478ef, 
////                         0xbbd87a5257e5f8b9, 0x1331d8bc1872c548, 0xa5dd30ce23ae8df2, 0x26c0065f5045c2e7, 0xa88da735f2d3fded, 
////                         0xa79382b60fd94c8, 0x579c81bc87c82cfd,
////                         0,0,0,0,0,0,0,0,
////                            0,0,0,0,0,0,0,0,
////                            0,0,0,0,0,0,0,0,
////                            0,0,0,0,0,0,0,0};   
//                          
//ulong p[64] = {0x7bd303ce1f1f2451, 0x7c62f1fa11787145, 0xf0638e5ce6d445db, 0xb3c6d48947a9306f, 0x133bdc8ee0911b78, 
//                           0xf9184b4559e3d806, 0x61e3b75abddf026e, 0x51063d049b32ef48, 0x57f3272a0ec1cdbe, 0xb772ea1b8f26b1a8, 
//                           0xd2920add117b4f49, 0x9eac94e03619a0ba, 0xdb4ad266c990c520, 0xe64cc4a4de22734, 0x64f37b2381a608ba, 
//                           0xff3a8cadcd33b1b3,
//                           0,0,0,0,0,0,0,0,
//                           0,0,0,0,0,0,0,0,
//                           0,0,0,0,0,0,0,0,
//                           0,0,0,0,0,0,0,0,
//                           0,0,0,0,0,0,0,0,
//                           0,0,0,0,0,0,0,0};  
//                           
//ulong q[64] = {0x9cc9f2330d80fec1, 0x68bfd3c62deefac3, 0xd43c951b72a36a16, 0xb3bc7c6e9fba8817, 0x28f9adb65b2aa530, 
//                           0x3e30927990667480, 0xbda178fe899a6cc0, 0x8ba9e43b0058396e, 0x2c81133dd195ce27, 0xe83f5a59034ba788, 
//                           0xa0e8006e8f95b58f, 0xdcc5bc6bed191311, 0xbb4b73795a93e39b, 0x6c7423481f544220, 0x4e24635e8bd04cc2, 
//                           0xf44157e2a022935a,
//                           0,0,0,0,0,0,0,0,
//                           0,0,0,0,0,0,0,0,
//                           0,0,0,0,0,0,0,0,
//                           0,0,0,0,0,0,0,0,
//                           0,0,0,0,0,0,0,0,
//                           0,0,0,0,0,0,0,0};  
//  
////my result                       
//ulong c[64] = {0xa9225a3f,0x71cff4fe,0x163a454d,0x040c99b7,0x0c377713,0xdbe305d5,0x1ca1dfe0,0xaf634026,
//                           0x7567e466,0x02bd45cc,0xaf403c98,0xa1e09be7,0x222e6a5a,0x32847c42,0x4069915d,0xe65c6dbd,
//                           0xda9965d1,0x670fe90b,0x7db6e2f4,0x545ca8c3,0x3392ed31,0x6caafacd,0x370bc83d,0x7e31f737,
//                           0x967b8f06,0x6cb774fa,0x9e5acc1e,0x3911d817,0xfb090120,0x2150cc5f,0xdfeaeae9,0x1193acb0,
//                           0x4ad23a1d,0x325fb0ed,0x2fbc2298,0x1fd4ac31,0xc52474a6,0x88938280,0x6a765db4,0x7264e9e3,
//                           0x6de20185,0x8cc26439,0xb3a0aab3,0x16b3c322,0xcab204cf,0xe2f4e927,0xc33b826f,0x437269c7,
//                           0x782c3078,0x039fbe94,0x99212e06,0x32d0ce0c,0x29e01a59,0x59ba5286,0x4a836d20,0x5189f6a5,
//                           0x10f421f5,0xf0c7d198,0xb3572c36,0x4ef96213,0xae49b6d4,0xe40aaf8c,0x8b58d77e,0x1b41ba27};

////new data
//ulong n[64]={0x9bebbb80d92aeacb, 0xa4d1c50c3cb90d4, 0xe4e7e25452f7614, 0x7cc9ed9a765f73db,
//                          0xcda74149c6d68b4c, 0xe8098f53152a6e1a, 0x8093dd18a9a92d54, 0x15ec5fc2a0a828e2,
//                          0xe5177a98942bc34c, 0x3c827519ad52efe3, 0xcf2c93e82b953313, 0xf26995e04fac8397,
//                          0xa67c43e467d7e2c3, 0xadeb65d6ee0c1d71, 0x92b3b27fc92f3b26, 0xb59279afb2f7a7d3,
//                          0x3bcc26e2bb9ebb71, 0xab1863fb3ce40c8, 0xb5de6a7732e12542, 0x165caa7b91861a94,
//                          0x725be0b8ef25a5b9, 0x1966f40feea0d58e, 0x1dc65fbb0b82c902, 0x159ec68e4aff1b39,
//                          0x15530655f6e7ffbe, 0x61795655982ee535, 0x6425b6efd4f8b3da, 0x80a538fbea13bc7f,
//                          0x79dffe13ca43e033, 0x8af279f488d1c203, 0xce83e60e056a3f3e, 0xa4ae21de8f3735df,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//
//ulong R[64] = {0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0};
//
//
//ulong d[64]={0xbe8e6815ac08f771, 0x441dd579f4618f00, 0x9687f5530d35fd40, 0xa3e1ad51cb3cc18a,
//              0x97434839806420e7, 0xe9350a109d9fff0c, 0xd56c7ae8da978b6, 0x5bd53701884fac59,
//              0x68d0415b75f7d4fd, 0x347a786169d52a44, 0x694175f39b0c209a, 0xa663f7567591651c,
//              0x683f99238bb7d897, 0xeabc7d9197063eec, 0x5338b5f87168c867, 0xeded58e57c647b24,
//              0x23a8610cfcea2a1a, 0x9c0c8a2128dae731, 0x1378b5d033092585, 0xa22e3d153cc5ac42,
//              0x6dba863c07b73781, 0xb5ea05d90897d0a, 0x5a3217642b55b07b, 0xf3d058303cb2cc50,
//              0xb9b8be7c721def88, 0xe983331defeafaec, 0x250c002dde41215f, 0xe0e0d46e3b65ed80,
//              0x88cf132ab754df05, 0x3bae937b531f6837, 0xc64e92146d92eb10, 0xa2ab83b755dee2af,
//              0,0,0,0,0,0,0,0,
//              0,0,0,0,0,0,0,0,
//              0,0,0,0,0,0,0,0,
//              0,0,0,0,0,0,0,0};
//
//
//
//ulong e[64]={0x10001,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};//10001
//
//ulong mm[64] = {0xa3cb88a1,0x32c4b24c,0x8e177b87,0x952d6cd1,
//                           0xb7a99a0a,0xea2153b6,0x63922e9e,0x259809ca, 
//                           0xd9e6afb9,0x67002979,0xa8e1fe94,0x1ba0c49d,
//                           0xf1363217,0xbda8dee6,0x8b4cf0de,0xcd421fda,
//                           0x843566eb,0xebf2e0fa,0xcbc317f6,0xffe350a2,
//                           0xacb57ff6,0xf0e7e47d,0x21eb5d7b,0x881f57b5,
//                           0x460a639d,0xee59a025,0x79baa078,0x09b4d52e, 
//                           0x7d8bc32c,0xc3b2411d,0x8edc60fe,0xeaad1da8,
//                           0xf8d3aaf9,0x3c29f894,0xe3dd011d,0xf80aa234, 
//                           0x7ed149e0,0xdb8dab5a,0xea20c49c,0x271f30e0,
//                           0xc4b41b8b,0xff58ee3d,0x352ec303,0xb58e0921,
//                           0x623830ea,0x017c0e14,0xc09136c1,0x0bd58a1c, 
//                           0x531a9db4,0x626f4977,0x7fea460f,0xc4a023fa,
//                           0x14d54644,0x57375753,0x68d8fa8c,0xef474b89,
//                           0x500b891c,0x1091e0d2,0x0cbb4b32,0x5020a134,
//                           0xad4e5397,0xc02a85a2,0xb348c7ac,0x4285f7b3};
//
//ulong c[64] = {   0x8a9b0303,0x10e74e48,0x8c96b16d,0x5ca85e5a,
//                              0xc87d8577,0x936a992a,0xd3ac6d64,0x09e56c11,
//                              0x719b0ee3,0xdaf1f109,0x6522ffe3,0xc5cfe17a,
//                              0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0};
//
//////my result to m=c^e mod n                      
//ulong m[64] =  {0xf7b869a4,0xb651507b,0xfe0ac6ad,0x9328ef84,0x5063c9a6,0xe4a676c8,0x4fd8074d,0xc5fa19b1,
//                              0x4a748d5b,0x0d80f109,0xebdb8703,0xb8e176a9,0x638eb40b,0x1d07e329,0x0046dd69,0xb9130975,
//                              0x9e4ecb39,0x8adfc220,0xeedf5ea1,0x2c581544,0x3af3e1d2,0x9c95a188,0x5afbc4c5,0xa43de637,
//                              0xa34081ba,0x69881fbd,0x2e123ee3,0x71ab7a19,0xd99288cd,0xce2a68e2,0x8998727b,0xd52bc919,
//                              0x65585591,0x63b46a36,0x5b2816ca,0xa4d19178,0x24fafe3a,0x7e11a764,0x0a21099a,0x45312b5d,
//                              0xefbb09d4,0x003b7d77,0x41ebccda,0xa6e7fd1f,0xdb4de10b,0x7484e14b,0x975b38ff,0x8d17bf0a,
//                              0x6b19680f,0xfc9a755b,0x0c7d5d06,0xa34baa09,0x8e7687b2,0x70af401e,0x9d41266b,0x4acc10e0,
//                              0xdf98d058,0x70d1ec4b,0xcde8cf6e,0xd4adc800,0x6f41c04c,0xe4f62d2a,0xee2984c7,0x54fa0e23};
                            
////new data2
//ulong n[64]={ 0xf14a6ea78302f3bb, 0x8b46588f42788026, 0xd8b09b67d067745f, 0x92fc103ea06fbc98,
//                          0x52b8bc5e1cf0eab6, 0x230a440d862e8535, 0x2c0152719c0dfa61, 0x5a1b93fea67be9a7,
//                          0x58a06186928f762,  0x2457ed55ace01fa4, 0xebbeaaf1d0de8308, 0xcbd3280e3bf30a49,
//                          0xd90b7049f49aad33, 0x5ae06e57c5c8ae54, 0xf1e2f05345aad820, 0xd66c5dde75ba7c90,
//                          0x63d020819211284c, 0x474584daf93fd447, 0x19f442c64c7e314e, 0x24dea9460c21be4c,
//                          0x18be829141577972, 0x52bb140136c54bf0, 0xeb327a8fb9bd6b52, 0xf8d69a8a678d790,
//                          0x14d135e4e52fe9ff, 0xeff64ad6e8fbd9be, 0x5dc618f3e8125088, 0xed68ed93acb63489,
//                          0x88a5f2f8b4835ac0, 0x8a6a14df18a55fe2, 0xde23823ef93e114b, 0xcdab9ad3beb167e8,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//
//
//ulong d[64]={ 0xaf73a26ab6f52001, 0x9a7643511d8753ac, 0xb40667fc0f421db1, 0xad65dc73173f646d,
//                          0x5ac0f81ed7156630, 0x1bb5f3243aede36, 0x552ef65dcaf5427b, 0x1485aaf8f5f84cd4, 
//                          0x98d6ac17e1580a24, 0x51748cb48de23857, 0xa4c93ef766bbd93d, 0x80dbe0fad1856f60,
//                          0x4c3678eedf2177d3, 0x99917f1ed0bbd63d, 0x17752488ec4fdcec, 0x946f4786fa723beb,
//                          0xf562c14e90e1fd0d, 0xb516dc2420845e2e, 0x3da5f21b80d5d8ee, 0x36f06ca3ba90106e, 
//                          0x8edbdd630d5b1c23, 0x618d00f03b71125, 0x3551a09f864b5966, 0x8b8e78fd5520881c,
//                          0x3eb292b54564d650, 0x1f82c34b632148db, 0xaee7e8fe64eefe63, 0x815e512ad6f8fbbe,
//                          0x117b87cd56b85fc0, 0x94cfca2bc7b4bfe9, 0x29c2f0d27cf4431c, 0xcbaf0f7e74742d7c,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//                          
//ulong e[64]={0x10001,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//                          
//ulong R[64] = {0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0};
//                          
//ulong mm[64]={    0x98fbbd73,0x74da05a4,0x8bd79003,0x97f78333,
//                          0x4f10aeb7,0x89cbe50f,0x961b066f,0x1461d9cd, 
//                          0x300cf548,0x0cd79415,0x5ab0a212,0x2aa7aed2,
//                          0x518b11cd,0xeec5897d,0x7ae5e050,0xc3a99d58,
//                          0x4873986c,0xbbefb660,0xd52ea40d,0x1a1112ad,
//                          0x05785c11,0x2fb2de66,0xab23e300,0x68ffe363,
//                          0x0496e749,0x60fda5a8,0x30fd9380,0xb76f2829,
//                          0x6f169c58,0xb1708020,0xe7a423ff,0x902c26d0,
//                          0xd3dd6a29,0x7b89978e,0x5d0ccde7,0xafb23e58,
//                          0x4b0efd3a,0x1b70a5ed,0xa0b0a28e,0x9394a038,
//                          0x74a7ddcb,0xb9c3aad6,0xaa0d3c1c,0xbbcbe886,
//                          0x7f56b7c6,0x865ef41f,0x4ae0a653,0xcef18c50,
//                          0xd43e4bb3,0xa45cc6d5,0x17b10f40,0x9320b7f6,
//                          0x20e2c94b,0xbabd3492,0xa7f2ce67,0x8c43a4ff,
//                          0xf8600d6d,0x903ac936,0x99f9a919,0x2d4e4663,
//                          0x423a826d,0x0be1efd8,0x6a68a5af,0xccdff217};
//
//ulong c[64] = {   0x8a9b0303,0x10e74e48,0x8c96b16d,0x5ca85e5a,
//                              0xc87d8577,0x936a992a,0xd3ac6d64,0x09e56c11,
//                              0x719b0ee3,0xdaf1f109,0x6522ffe3,0xc5cfe17a,
//                              0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0};
//
//ulong m[64] = {   0x5344d63e,0xb6b1c9d1,0x8f92895d,0x63c934c4,0x47dd79f1,0x28facb26,0xf73c6eb1,0x8c97490e,
//                              0x65b9b052,0x30ac425c,0xa84b92b6,0x3eeb8d20,0x15120a0c,0xe88924c5,0x1115021a,0xd9d2ff9d,
//                              0x14b3846f,0xc87e3e9d,0x48a40473,0x2064e8eb,0x4a2bf072,0x24616344,0x0bae6cff,0xed837006,
//                              0xa66638ce,0x3d34f7dc,0x38e0328b,0x82d271d7,0x5c97b9b2,0x8f5c556b,0x7abe3e41,0x48f5201e,
//                              0x997188d6,0xb2038772,0x52c34e14,0xff9a7236,0x347c0650,0xfc051a2c,0x6e05f512,0x5c1d195a,
//                              0x9fc2c3f5,0xa17c9a24,0x6e126fa3,0x0665c4ed,0xa4ec971e,0x55dd2d80,0xf0968113,0x1b679ca0,
//                              0x964b8e8b,0x61aa3d61,0x7b8bbe95,0x139b148a,0xd496d011,0x2b1dbad3,0x398ace7a,0xc365c484,
//                              0x7f31017f,0x2ab48c08,0x1fdfff24,0x612790c1,0xa69bd0a3,0xae80c882,0x69411723,0xb4b07754};
                            
////new data3                       
//ulong n[64]={ 0x56234fe2fff64abb, 0xf93a53e0526f59bd, 0xea257597d1b86a53, 0xf7b2f8c250c1eae7,
//                          0xe939b6a9302e9db0, 0x6e849bc8a66ae090, 0x15d23334e33142b, 0xe416ab10189d9988,
//                          0x7e1aa8de4337312b, 0x8794bbf95e644e7c, 0xddc358d28bd8b8d7, 0xa53f2f280fa8dff0,
//                          0xa6adfe3e7ba870a0, 0x486015bdb68226b5, 0x3dc4c02dbc77100a, 0x79dcb2494cee7d31,
//                          0x2668d2080c535f90, 0xee8bd2e4788da9b5, 0x2c56b71090e66be4, 0x5434739b338bf515,
//                          0x172a4b340b7519cc, 0xf46171bee25f69a8, 0x4c502499a5902249, 0x1a8da963e6b73b89, 
//                          0x527f94be77a69c21, 0xcc43aa7c2b0ad181, 0x7512abc2b2e4689d, 0x8e6a2d77942cee45,
//                          0xc6cc98ba9d8fd675, 0x1c6ef2e21915026b, 0x11eb7749ba18d06a, 0xb4c822f2eee5a5e6,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//
//ulong d[64]={ 0x91d9582f1cf6a5c1, 0x1d377f50f2dd46e3, 0xdbd14e5919f9c270, 0x12993d08e5b5b11d,
//                          0x311ac687299d70c9, 0xed60f2f86710d395, 0x75af53bbdea03d04, 0x207ea573f1976188,
//                          0x5070a1dfab258e8a, 0x485b90c921bc03bb, 0x673c9cb11c5814bf, 0x3e79f78ac121a14e,
//                          0x5dd0a39f15e721f, 0xe9b186817305f9d5, 0xcca088820eb52356, 0x4a80f48381c8e4f2,
//                          0x81ce7482941f916c, 0x7c0c4f7be12f82c3, 0x9edd4b7d606b31e6, 0x688ebeff94a60989,
//                          0x6e26fc7a2dc3c97, 0x150a009295619a0c, 0xf4ebbd106c29a3ed, 0x16cd58f4969d3e03,
//                          0xf60b4829bf5210a3, 0xa5a182cdbb9aaf70, 0xef0a366449791d91, 0x8f91a8a1c20b5a6c,
//                          0x2ab3d1d779f33854, 0x56a8d764aa4e3cc6, 0x86e6bd8af636a340, 0x6d3531979ba57310,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//                          
//ulong e[64]={0x10001,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//                          
//ulong R[64] = {0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0};
//               
//ulong c[64] = {   0x8d9f0303,0x48c45462,0xc29e27d5,0xc5d4a5d6,0x87c434c9,0x7d8b143c,0xc76716c8,0xd112cabc,
//                              0xbec49bb5,0x526b3a1d,0x8f9ccee9,0xc3ad25b7,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0};
//                              
//ulong m[64] = {   0xa44a5da1,0x2d7a10f9,0x3e611437,0x268c8461,0x91825874,0x4e2e64f0,0x8aa61b2d,0x4313eb91,
//                              0xfe3f8a61,0x6086ed11,0xe107261f,0xfab08f40,0xdcd4c91c,0x2e575e14,0xf1d97b31,0x51f00ad3,
//                              0x4974fb15,0x22226018,0x88dd5ec3,0xd9028da8,0xa1e1ab7e,0xc207b9c2,0xae01662e,0x97aa7113,
//                              0xeb29edf1,0x8d2a5a01,0x54128aea,0x5d6d6b63,0x31ca219f,0x7a540479,0xac32edc1,0x26d51570,
//                              0xed0f95af,0xd5a22cd6,0x5cc47a4a,0x01867d38,0x695ebfdf,0x49a3f7cd,0x3c52aabd,0x87297d72,
//                              0x7b6cb6fc,0xe9b21022,0x3f7f1300,0x51de3030,0x6b082c30,0x2dacfde0,0x6685e1bf,0xceb6d63b,
//                              0x3890a61e,0x03bacb87,0x4f523791,0xfb4c4f70,0x28fe777f,0x3e0731e2,0x00e454cc,0xc7dd8c99,
//                              0x77371e3c,0x8767b912,0xfbdad567,0x7be6845f,0x4a2e391a,0x3ea1d14f,0x8e5036da,0x347aad6b};

////test data
//ulong n[64] = {   0x9bebbb80d92aeacb, 0xa4d1c50c3cb90d4, 0xe4e7e25452f7614, 0x7cc9ed9a765f73db, 0xcda74149c6d68b4c, 
//                              0xe8098f53152a6e1a, 0x8093dd18a9a92d54, 0x15ec5fc2a0a828e2, 0xe5177a98942bc34c, 0x3c827519ad52efe3, 
//                              0xcf2c93e82b953313, 0xf26995e04fac8397, 0xa67c43e467d7e2c3, 0xadeb65d6ee0c1d71, 0x92b3b27fc92f3b26, 
//                              0xb59279afb2f7a7d3, 0x3bcc26e2bb9ebb71, 0xab1863fb3ce40c8, 0xb5de6a7732e12542, 0x165caa7b91861a94, 
//                              0x725be0b8ef25a5b9, 0x1966f40feea0d58e, 0x1dc65fbb0b82c902, 0x159ec68e4aff1b39, 0x15530655f6e7ffbe, 
//                              0x61795655982ee535, 0x6425b6efd4f8b3da, 0x80a538fbea13bc7f, 0x79dffe13ca43e033, 0x8af279f488d1c203, 
//                              0xce83e60e056a3f3e, 0xa4ae21de8f3735df,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0};
//
//ulong d[64] = {   0xbe8e6815ac08f771, 0x441dd579f4618f00, 0x9687f5530d35fd40, 0xa3e1ad51cb3cc18a, 0x97434839806420e7, 
//                              0xe9350a109d9fff0c, 0xd56c7ae8da978b6, 0x5bd53701884fac59, 0x68d0415b75f7d4fd, 0x347a786169d52a44, 
//                              0x694175f39b0c209a, 0xa663f7567591651c, 0x683f99238bb7d897, 0xeabc7d9197063eec, 0x5338b5f87168c867, 
//                              0xeded58e57c647b24, 0x23a8610cfcea2a1a, 0x9c0c8a2128dae731, 0x1378b5d033092585, 0xa22e3d153cc5ac42, 
//                              0x6dba863c07b73781, 0xb5ea05d90897d0a, 0x5a3217642b55b07b, 0xf3d058303cb2cc50, 0xb9b8be7c721def88, 
//                              0xe983331defeafaec, 0x250c002dde41215f, 0xe0e0d46e3b65ed80, 0x88cf132ab754df05, 0x3bae937b531f6837, 
//                              0xc64e92146d92eb10, 0xa2ab83b755dee2af,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0};
//
//ulong e[64]={0x10001,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0,
//                          0,0,0,0,0,0,0,0};
//
//ulong R[64] = {0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0,
//               0,0,0,0,0,0,0,0};
//
//ulong m[64] = {   0x3a6028a87b975593, 0x6983251db9f92ad0, 0x45728d5aebb60536, 0x5bfe350e29b59c0, 0xefbf1b64e85f4193, 
//                              0x8771fe3f967fc7e7, 0x76faf8685a8c7417, 0x4fa9aaece2876cfa, 0xc5a3dd8ce961f117, 0x5dcc8a7876bbd884, 
//                              0x2d362fd4fe805c9d, 0x348d69b5d8a8c742, 0x9ddb42c7ea5c1465, 0x67ca5b44ef8f3eb1, 0xe616ce53ea53a3c0, 
//                              0x540b49916dff1921, 0xcbd30bea2bc5c219, 0xc325f2a4cd4347b1, 0x4cb250ee05b85972, 0x5d7e177bd64678b9, 
//                              0xf05caa943ea28a3, 0x4e4820dc71e9b04e, 0x7f1ff140012a20cf, 0xd37e2e23b803ed0a, 0xdb6eabb2d64db0be, 
//                              0x5efea30eb0411ad5, 0xaecd98954089bc3c, 0x75ccec54397b6908, 0xf693bee0ee3a5ca0, 0xcda6fa9cb933c24a, 
//                              0x2ed04043eea5b2db, 0x19c92ed5cd895530,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0};
//
//ulong c[64] = {   0x22afcfedcce9cf07, 0x6eaef795878cfc52, 0x5dc7eb08f9749fd4, 0xdcf1d6fca1cb67dc, 0x953b2f1b5b4f73e7, 
//                              0x13797eb01c6f6bc6, 0x4594707fa064e25e, 0x14f4d17504dc41d5, 0x3213f5b7c726e1b7, 0xf94c359cb83c740, 
//                              0xdded6b4f241775b, 0x70ab8b81e632a70b, 0xfbe868543c4d4935, 0x2797aaed1f5660e1, 0x83ce603cfbad357b, 
//                              0xe617af457a5081c0, 0xe36d21eb3ab3c385, 0x67ab8ce29d5aa7b8, 0x733c1c9e98059f6e, 0xdb5620f15a780355, 
//                              0x7cb24ac147580e66, 0xcd5debe1cbd4b7a3, 0x8e0e7ed416b09464, 0x89952e4120f95aed, 0x426ab61f8ca2de1f, 
//                              0x63c5a8f950130778, 0xcccde187042a59f5, 0x24c04a96034f6fc6, 0x5b33518379c9de7c, 0x6a48cea6d9b64dd6, 
//                              0x53dea138d1608160, 0x4abeb7db267c82cb,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0,
//                              0,0,0,0,0,0,0,0};


ulong c1[64] = {1,0,0,0,0,0,0,0,
                             0,0,0,0,0,0,0,0,
                             0,0,0,0,0,0,0,0,
                             0,0,0,0,0,0,0,0,
                             0,0,0,0,0,0,0,0,
                             0,0,0,0,0,0,0,0,
                             0,0,0,0,0,0,0,0,
                             0,0,0,0,0,0,0,0};
                            
                        
ulong exgcd(ulong a,ulong b,ulong &x,ulong &y)
{
    if(b==0) {x=1;y=0;return a;}
    else 
    {
        ulong d=exgcd(b,a%b,x,y);
        ulong t=x;
        x=y;
        y=t-a/b*y;
        return d;
    }
}

ulong eculid(ulong num,ulong mod)
{
    ulong x,y;
    exgcd(num,mod,x,y);
    while(x<0) x+=mod,y-=num;
    return x;
}

//InfInt exgcd(InfInt a,InfInt b,InfInt &x,InfInt &y)
//{
//    if(b==0) {x="1";y="0";return a;}
//    else 
//    {
//        InfInt d=exgcd(b,a%b,x,y);
//        InfInt t=x;
//        x=y;
//        y=t-a/b*y;
//        return d;
//    }
//}
//InfInt eculid(InfInt num, InfInt mod)
//{
//  InfInt x,y;
//  x = "0";
//  y = "0";
//  exgcd(num,mod,x,y);
//  while(x<0) x+=mod,y-=num;
//  return x;
//}

void calculateR(uint *a, int aNum, uint *n, int nNum, FILE *fp){//
    int i,cnt,bit_move,byte_move,offset,sub,pos,an,nn,temp;
    uint *nT,next;
    unsigned long temp1,temp2,temp3;
    an = aNum;
    nn = nNum;
    nT = new unsigned int [an/32+1];

    //sub
    cnt = 0;
    while(1){//while
        //
        if(an>nn)
            bit_move = an - nn - 1;
        else
            bit_move = 0;
        //if(bit_move>31)
        byte_move = bit_move/32+1;
        offset = bit_move%32;
        next = 0;
        for(i=0; i<(an/32+1); i++)
            nT[i] = 0;
        for(i=(nn/32); i>=0; i--){//move
            temp1 = n[i];
            temp2 = (temp1<<offset);
            nT[i+byte_move] = ((temp2>>32)&0xffffffff) + next;
            next = (temp2&0xffffffff);
        }//move
        for(i=0; i<byte_move; i++)
            nT[i] = 0;
        nT[byte_move-1] = next;
        //fprintf(fp,"\n nT: an:%d  nn:%d  bit_move:%d  byte_move:%d \n", an, nn, bit_move, byte_move); 
        //for(i=0; i<(an/32+1); i++){//
    //  fprintf(fp,"  %x",nT[i]);
    //  if((i%8)==7)    fprintf(fp,"\n");       
    //}// 
    //fprintf(fp,"\n");
        
        sub = 0;
        temp1 = 0x100000000;
        //for(i=(aNum/32+1); i>=0; i--){
        for(i=0; i<(an/32+1); i++){//sub
            if((nT[i]+sub)>a[i]){//             
                a[i] = temp1 + a[i] - nT[i] - sub;
                sub = 1;
            }//
            else{//
                a[i] = a[i] - nT[i] - sub;
                sub = 0;
            }           
        }//sub
        
        //judge large or small
        pos = 0;
        for(i=(an/32); i>=0; i--){
            if(a[i]!=n[i]){
                pos = i;
                break;
            }
        }
        //fprintf(fp,"judge after! pos:%d cnt:%d an:%d a:%x n:%x\n",pos,cnt,an,a[pos],n[pos]);
        if(a[pos]<n[pos] || cnt>0x4000)
            break;  
        else{//
            for(i=31;i>=0;i--){//
                if(((a[pos]>>i)&1)>0){
                    an = 32*pos + i + 1;
                    break;
                }
            }//end for
        }//end else
        ////fprintf(fp,"\n");
        /////////printf(" aNum: %d  byte_move:%d\n", an, byte_move);
        //fprintf(fp,"\n");
        //fprintf(fp,"result: pos:%d  i:%d  aNum:%d  bit_move:%d  byte_move:%d \n", pos, i, an, bit_move, byte_move);   
        //for(i=0; i<(an/32+1); i++){//
    //  fprintf(fp,"  %x",a[i]);
    //  if((i%8)==7)    fprintf(fp,"\n");       
    //}// 
    //fprintf(fp,"\n");
    
    cnt = cnt + 1;
    }//end while
}//

//void m64to27(ulong *a,ulong *b)
//{
//    b[0] = a[0]&0x7ffffff;
//    b[1] = (a[0]>>27)&0x7ffffff;
//    b[2] = ((a[0]>>54)&0x3ff) + (a[1]&0x1ffff);
//    b[3] = (a[1]>>17)&0x7ffffff;
//    b[4] = ((a[1]>>44)&0xfffff) + (a[2]&0x3f);
//    b[5] = (a[2]>>7)&0x7ffffff;
//    b[6] = (a[2]>>34)&0x7ffffff;
//    b[7] = ((a[2]>>61)&0x7) + (a[3]&0xffffff);
//    b[5] = (a[3]>>24)&0x7ffffff;
//    b[6] = (a[3]>>51)&0x1fff + (a[4]&0x3fff);
//    b[5] = (a[3]>>24)&0x7ffffff;
//}

#endif

#endif


